﻿/**
 * File:   setting_slider.h
 * Author: AWTK Develop Team
 * Brief:  setting_slider
 *
 * Copyright (c) 2018 - 2024  Guangzhou ZHIYUAN Electronics Co.,Ltd.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * License file for more details.
 *
 */

/**
 * History:
 * ================================================================
 * 2018-04-02 Li XianJing <xianjimli@hotmail.com> created
 *
 */

#ifndef TK_SETTING_SETTING_SLIDER_H
#define TK_SETTING_SETTING_SLIDER_H

#include "base/widget.h"
#include "tkc/str.h"

BEGIN_C_DECLS

#define SETTING_SLIDER_MAX_SCALE_NUM 100

/**
 * @class setting_slider_t
 * @parent widget_t
 * @annotation ["scriptable","design","widget"]
 * 滑块控件。
 *
 * setting_slider\_t是[widget\_t](widget_t.md)的子类控件，widget\_t的函数均适用于setting_slider\_t控件。
 *
 * ```xml
 * <!-- ui -->
 *  <setting_slider min="3" max="150" value="50" name="setting_slider" style="settings" w="115" h="344" bar_size="6" dragger_size="15" serial="3;5;10;20;40;60;80;100;120;150;" step="1"/>
 * ```
 * 
 * ```xml
 * <!-- style -->
 * <setting_slider>
 *   <style name="settings" bar_size="6" bg_color="#00C2FF" dragger_size="15" fg_color="#D9D9D9"  font_size="18" highlight_font_size="25">
 *      <normal border_color="#C5E7FF"/>
 *      <pressed border_color="#00FFFF"/>
 *   </style>
 * </setting_slider>
 * ```
 */
typedef struct _setting_slider_t {
  widget_t widget;
  /**
   * @property {double} value
   * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
   * 值。
   */
  double value;

  /**
   * @property {double} step
   * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
   * 拖动的最小单位(用于键盘，鼠标默认步长1)。
   */
  double step;

  /**
   * @property {uint32_t} bar_size
   * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
   * 轴的宽度或高度（单位：像素），为0表示为控件的宽度或高度的一半，缺省为0。
   */
  uint32_t bar_size;

  /**
   * @property {uint32_t} dragger_size
   * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
   * 滑块的宽度或高度（单位：像素），缺省为 bar_size * 1.5。
   */
  uint32_t dragger_size;

  /**
   * @property {char*} line_cap
   * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
   * 前景色的线帽形状。（取值：butt|round，默认为跟随风格的圆角设置, 但是在没有设置圆角的时候无法使用 "round" 来设置圆角）
   */
  char* line_cap;


  /**
   * @property {bool_t} dragger_adapt_to_icon
   * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
   * 滑块的宽度或高度是否与icon适应，缺省为true。
   */
  bool_t dragger_adapt_to_icon;

  /**
   * @property {bool_t} slide_with_bar
   * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
   * 是否允许在轴上滑动来改变滑块位置，缺省为FALSE。
   */
  bool_t slide_with_bar;

  /**
   * @property {uint32_t} drag_threshold
   * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
   * 拖动临界值。
   *
   */
  uint32_t drag_threshold;

  /**
   * @property {str_t} serial
   * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
   * 刻度的序列值，格式如：1;5;10;, 每个刻度数必须从小到大, 以;结尾, 最大100个刻度
   */
  str_t serial;

  /**
   * @property {bool_t} is_reverse
   * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
   * 刻度是否反向显示（上大下小）
   */
  bool_t is_reverse;

  /**
   * @property {double} min
   * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
   * 最小值
   */
  double min;
  
  /**
   * @property {double} max
   * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
   * 最大值
   */
  double max;

  /*private*/
  bool_t pressed;
  bool_t dragging;
  bool_t no_dragger_icon;
  bool_t auto_get_dragger_size;
  double saved_value;
  point_t down;
  rect_t dragger_rect;
  rect_t tag_rect;
  struct st_scale{
    int value;
    int line_y; 
  } scales[SETTING_SLIDER_MAX_SCALE_NUM];
  bool_t is_key_long_pressed;
} setting_slider_t;

/**
 * @event {value_change_event_t} EVT_VALUE_WILL_CHANGE
 * 值即将改变事件。
 */

/**
 * @event {value_change_event_t} EVT_VALUE_CHANGING
 * 值正在改变事件(拖动中)。
 */

/**
 * @event {value_change_event_t} EVT_VALUE_CHANGED
 * 值改变事件。
 */

/**
 * @method setting_slider_create
 * 创建setting_slider对象
 * @annotation ["constructor", "scriptable"]
 * @param {widget_t*} parent 父控件
 * @param {xy_t} x x坐标
 * @param {xy_t} y y坐标
 * @param {wh_t} w 宽度
 * @param {wh_t} h 高度
 *
 * @return {widget_t*} 对象。
 */
widget_t* setting_slider_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);

/**
 * @method setting_slider_cast
 * 转换为setting_slider对象(供脚本语言使用)。
 * @annotation ["cast", "scriptable"]
 * @param {widget_t*} widget setting_slider对象。
 *
 * @return {widget_t*} setting_slider对象。
 */
widget_t* setting_slider_cast(widget_t* widget);

/**
 * @method setting_slider_set_value
 * 设置滑块的值。
 * @annotation ["scriptable"]
 * @param {widget_t*} widget 控件对象。
 * @param {double}  value 值
 *
 * @return {ret_t} 返回RET_OK表示成功，否则表示失败。
 */
ret_t setting_slider_set_value(widget_t* widget, double value);

/**
 * @method setting_slider_set_min
 * 设置滑块的最小值。
 * @annotation ["scriptable"]
 * @param {widget_t*} widget 控件对象。
 * @param {double}  min 最小值
 *
 * @return {ret_t} 返回RET_OK表示成功，否则表示失败。
 */
ret_t setting_slider_set_min(widget_t* widget, double min);

/**
 * @method setting_slider_set_max
 * 设置滑块的最大值。
 * @annotation ["scriptable"]
 * @param {widget_t*} widget 控件对象。
 * @param {double}  max 最大值
 *
 * @return {ret_t} 返回RET_OK表示成功，否则表示失败。
 */
ret_t setting_slider_set_max(widget_t* widget, double max);

/**
 * @method setting_slider_set_line_cap
 * 设置前景色的线帽形状。（默认为跟随风格的圆角设置，但是在没有设置圆角的时候无法使用 "round" 来设置圆角）
 * @annotation ["scriptable"]
 * @param {widget_t*} widget 控件对象。
 * @param {const char*}  line_cap 前景色的线帽形状，取值为：butt|round
 *
 * @return {ret_t} 返回RET_OK表示成功，否则表示失败。
 */
ret_t setting_slider_set_line_cap(widget_t* widget, const char* line_cap);

/**
 * @method setting_slider_set_step
 * 设置滑块的拖动的最小单位。
 * @annotation ["scriptable"]
 * @param {widget_t*} widget 控件对象。
 * @param {double}  step 拖动的最小单位。
 *
 * @return {ret_t} 返回RET_OK表示成功，否则表示失败。
 */
ret_t setting_slider_set_step(widget_t* widget, double step);

/**
 * @method setting_slider_set_bar_size
 * 设置bar的宽度或高度。
 * @annotation ["scriptable"]
 * @param {widget_t*} widget 控件对象。
 * @param {uint32_t}  bar_size bar的宽度或高度。
 *
 * @return {ret_t} 返回RET_OK表示成功，否则表示失败。
 */
ret_t setting_slider_set_bar_size(widget_t* widget, uint32_t bar_size);

/**
 * @method setting_slider_set_vertical
 * 设置滑块的方向。
 * @annotation ["scriptable"]
 * @param {widget_t*} widget 控件对象。
 * @param {bool_t}  vertical 是否为垂直方向。
 *
 * @return {ret_t} 返回RET_OK表示成功，否则表示失败。
 */
ret_t setting_slider_set_vertical(widget_t* widget, bool_t vertical);

/**
 * @method setting_slider_set_drag_threshold
 * 设置拖拽临界值。
 * @annotation ["scriptable"]
 * @param {widget_t*} widget 控件对象。
 * @param {uint32_t}  drag_threshold 拖拽临界值。
 *
 * @return {ret_t} 返回RET_OK表示成功，否则表示失败。
 */
ret_t setting_slider_set_drag_threshold(widget_t* widget, uint32_t drag_threshold);

#define WIDGET_TYPE_SETTING_SLIDER "setting_slider"
#define SETTING_SLIDER_PROP_DRAGGER_SIZE "dragger_size"
#define SETTING_SLIDER_PROP_DRAGGER_ADAPT_TO_ICON "dragger_adapt_to_icon"
#define SETTING_SLIDER_PROP_SLIDE_WITH_BAR "slide_with_bar"
#define SETTING_SLIDER_PROP_SLIDE_LINE_CAP "line_cap"
#define SETTING_SLIDER_PROP_SERIAL "serial"
#define SETTING_SLIDER_PROP_IS_REVERSE "is_reverse"

#define SETTING_SLIDER(widget) ((setting_slider_t*)(setting_slider_cast(WIDGET(widget))))

/*public for subclass and runtime type check*/
TK_EXTERN_VTABLE(setting_slider);

/*public for test*/
ret_t setting_slider_dec(widget_t* widget);
ret_t setting_slider_inc(widget_t* widget);

/**
 * @method setting_slider_set_value_internal
 * 设置滑块的值(public for test)。
 *
 * @param {widget_t*} widget 控件对象。
 * @param {double}  value 值。
 * @param {uint32_t} etype 触发事件。
 * @param {bool_t} force 不管有没有变化都设置。
 *
 * @return {ret_t} 返回RET_OK表示成功，否则表示失败。
 */
ret_t setting_slider_set_value_internal(widget_t* widget, double value, uint32_t etype, bool_t force);

END_C_DECLS

#endif /*TK_SETTING_SETTING_SLIDER_H*/
